home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / tiff / tools / tiff2bw.c < prev    next >
C/C++ Source or Header  |  1992-03-26  |  5KB  |  175 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/tiff2bw.c,v 1.6 92/03/27 14:49:50 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include "tiffio.h"
  31.  
  32. typedef    unsigned char u_char;
  33. typedef    unsigned short u_short;
  34. typedef    unsigned long u_long;
  35.  
  36. #define    streq(a,b)    (strcmp((a),(b)) == 0)
  37. #define    CopyField(tag, v) \
  38.     if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
  39.  
  40. /* x% weighting -> fraction of full color */
  41. #define    CVT(x)    (((x)*255)/100)
  42. int    RED = CVT(28);        /* 28% */
  43. int    GREEN = CVT(59);    /* 59% */
  44. int    BLUE = CVT(11);        /* 11% */
  45.  
  46. usage()
  47. {
  48.     fprintf(stderr,
  49.     "usage: tiff2bw [-r red%%] [-g green%%] [-b blue%%] input output\n");
  50.     exit(1);
  51. }
  52.  
  53. main(argc, argv)
  54.     int argc;
  55.     char **argv;
  56. {
  57.     TIFF *in, *out;
  58.     u_long w, h;
  59.     u_short samplesperpixel, bitspersample, shortv, config;
  60.     float floatv;
  61.     register u_long row;
  62.     register int s;
  63.     u_char *inbuf, *outbuf;
  64.     char thing[1024];
  65.     u_long rowsperstrip;
  66.     int c;
  67.     extern int optind;
  68.     extern char *optarg;
  69.  
  70.     while ((c = getopt(argc, argv, "r:g:b:")) != -1)
  71.         switch (c) {
  72.         case 'r':
  73.             RED = CVT(atoi(optarg));
  74.             break;
  75.         case 'g':
  76.             GREEN = CVT(atoi(optarg));
  77.             break;
  78.         case 'b':
  79.             BLUE = CVT(atoi(optarg));
  80.             break;
  81.         case '?':
  82.             usage();
  83.             /*NOTREACHED*/
  84.         }
  85.     if (argc - optind < 2)
  86.         usage();
  87.     in = TIFFOpen(argv[optind], "r");
  88.     if (in == NULL)
  89.         exit(-1);
  90.     TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  91.     if (samplesperpixel != 3) {
  92.         fprintf(stderr, "%s: Not a color image.\n", argv[0]);
  93.         exit(-1);
  94.     }
  95.     TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  96.     if (bitspersample != 8) {
  97.         fprintf(stderr,
  98.             " %s: Sorry, only handle 8-bit samples.\n", argv[0]);
  99.         exit(-1);
  100.     }
  101.     out = TIFFOpen(argv[optind+1], "w");
  102.     if (out == NULL)
  103.         exit(-1);
  104.     CopyField(TIFFTAG_IMAGEWIDTH, w);
  105.     CopyField(TIFFTAG_IMAGELENGTH, h);
  106.     TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
  107.     TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
  108.     TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  109.     TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
  110.     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
  111.     sprintf(thing, "B&W version of %s", argv[optind]);
  112.     TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
  113.     TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw");
  114.     CopyField(TIFFTAG_ORIENTATION, shortv);
  115.     CopyField(TIFFTAG_XRESOLUTION, floatv);
  116.     CopyField(TIFFTAG_YRESOLUTION, floatv);
  117.     CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
  118.     outbuf = (u_char *)malloc(TIFFScanlineSize(out));
  119.     rowsperstrip = (8*1024)/TIFFScanlineSize(out);
  120.     TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
  121.         rowsperstrip == 0 ? 1L : rowsperstrip);
  122.     TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config);
  123.     switch (config) {
  124.     case PLANARCONFIG_CONTIG:
  125.         inbuf = (u_char *)malloc(TIFFScanlineSize(in));
  126.         for (row = 0; row < h; row++) {
  127.             if (TIFFReadScanline(in, inbuf, row, 0) < 0)
  128.                 break;
  129.             compresscontig(outbuf, inbuf, w);
  130.             if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
  131.                 break;
  132.         }
  133.         break;
  134.     case PLANARCONFIG_SEPARATE: {
  135.         int rowbytes = TIFFScanlineSize(in);
  136.         inbuf = (u_char *)malloc(3*rowbytes);
  137.         for (row = 0; row < h; row++) {
  138.             for (s = 0; s < 3; s++)
  139.                 if (TIFFReadScanline(in,
  140.                     inbuf+s*rowbytes, row, s) < 0)
  141.                      exit(-1);
  142.             compresssep(outbuf,
  143.                 inbuf, inbuf+rowbytes, inbuf+2*rowbytes, w);
  144.             if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
  145.                 break;
  146.         }
  147.     }
  148.     }
  149.     TIFFClose(out);
  150. }
  151.  
  152. compresscontig(out, rgb, n)
  153.     register u_char *out, *rgb;
  154.     register u_long n;
  155. {
  156.     register int v, red = RED, green = GREEN, blue = BLUE;
  157.  
  158.     while (n-- > 0) {
  159.         v = red*(*rgb++);
  160.         v += green*(*rgb++);
  161.         v += blue*(*rgb++);
  162.         *out++ = v>>8;
  163.     }
  164. }
  165.  
  166. compresssep(out, r, g, b, n)
  167.     register u_char *out, *r, *g, *b;
  168.     register u_long n;
  169. {
  170.     register int red = RED, green = GREEN, blue = BLUE;
  171.  
  172.     while (n-- > 0)
  173.         *out++ = (red*(*r++) + green*(*g++) + blue*(*b++)) >> 8;
  174. }
  175.